﻿using System;
using System.Collections.Generic;
using System.Reflection;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Controls;

namespace HangerSupport
{
	internal class Utils
	{
		public static XYZ PtTo2d(XYZ pt)
		{
			return new XYZ(pt.X, pt.Y, 0.0);
		}

		public static XYZ SetPtX(XYZ pt, double dVal)
		{
			return new XYZ(dVal, pt.Y, pt.Z);
		}

		public static XYZ SetPtY(XYZ pt, double dVal)
		{
			return new XYZ(pt.X, dVal, pt.Z);
		}

		public static XYZ SetPtZ(XYZ pt, double dVal)
		{
			return new XYZ(pt.X, pt.Y, dVal);
		}

		public static double Angle(XYZ vt)
		{
			return XYZ.BasisX.AngleOnPlaneTo(vt, XYZ.BasisZ);
		}

		public static double Angle(XYZ vtS, XYZ vtE)
		{
			return vtS.AngleOnPlaneTo(vtE, XYZ.BasisZ);
		}

		public static XYZ Rotate(XYZ vtIn, double dAngle)
		{
			double num = dAngle + Utils.Angle(vtIn);
			return new XYZ(Math.Cos(num), Math.Sin(num), 0.0);
		}

		public static XYZ Vector(double dAngle)
		{
			return new XYZ(Math.Cos(dAngle), Math.Sin(dAngle), 0.0);
		}

		public static void MessageBox(string strMsg)
		{
			YJKMessageBox.Show(strMsg);
		}

		public static bool IsEqual(double val1, double val2)
		{
			return !Utils.LessThan(val1, val2) && !Utils.LessThan(val2, val1);
		}

		public static bool LessThan(double val1, double val2)
		{
			return val1 - val2 < -1E-05;
		}

		public static double DoublePrecision(double dVal, int nDotNum = 1)
		{
			string format = "f" + nDotNum.ToString();
			string value = dVal.ToString(format);
			return Convert.ToDouble(value);
		}

		public static bool IsHorizontalPipe(Element pipe)
		{
			MEPCurve mepcurve = pipe as MEPCurve;
			bool flag = mepcurve == null;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				LocationCurve locationCurve = mepcurve.Location as LocationCurve;
				bool flag2 = locationCurve != null;
				if (flag2)
				{
					Curve curve = locationCurve.Curve;
					XYZ endPoint = curve.GetEndPoint(0);
					XYZ endPoint2 = curve.GetEndPoint(1);
					bool flag3 = Utils.IsEqual(endPoint.Z, endPoint2.Z);
					if (flag3)
					{
						return true;
					}
				}
				result = false;
			}
			return result;
		}

		public static bool IsVerticalPipe(Element pipe)
		{
			MEPCurve mepcurve = pipe as MEPCurve;
			bool flag = mepcurve == null;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				LocationCurve locationCurve = mepcurve.Location as LocationCurve;
				bool flag2 = locationCurve != null;
				if (flag2)
				{
					Curve curve = locationCurve.Curve;
					XYZ endPoint = curve.GetEndPoint(0);
					XYZ endPoint2 = curve.GetEndPoint(1);
					bool flag3 = Utils.IsEqual(endPoint.X, endPoint2.X) && Utils.IsEqual(endPoint.Y, endPoint2.Y);
					if (flag3)
					{
						return true;
					}
				}
				result = false;
			}
			return result;
		}

		public static double GetWallTypeStructureThick(Element wall)
		{
			double num = 0.0;
			Wall wall2 = wall as Wall;
			WallType wallType = wall2.WallType;
			bool flag = wallType != null;
			if (flag)
			{
				num = wallType.Width;
				num = HSFamily.feetToMM(num);
				CompoundStructure compoundStructure = wallType.GetCompoundStructure();
				bool flag2 = compoundStructure == null;
				if (flag2)
				{
					return num;
				}
				num = 0.0;
				IList<CompoundStructureLayer> layers = compoundStructure.GetLayers();
				foreach (CompoundStructureLayer compoundStructureLayer in layers)
				{
                    bool flag3 = (int)compoundStructureLayer.Function == 1;
					if (flag3)
					{
						num += compoundStructureLayer.Width;
					}
				}
				num = HSFamily.feetToMM(num);
			}
			return num;
		}

		public static double GetWallTypeStructureThickFromCenter(Element wall, XYZ ptIn, bool bOtherSide = false)
		{
			double num = 0.0;
			Wall wall2 = wall as Wall;
			WallType wallType = wall2.WallType;
			bool flag = wallType != null;
			if (flag)
			{
				num = wallType.Width / 2.0;
				num = HSFamily.feetToMM(num);
				CompoundStructure compoundStructure = wallType.GetCompoundStructure();
				bool flag2 = compoundStructure == null;
				if (flag2)
				{
					return num;
				}
				LocationCurve locationCurve = wall2.Location as LocationCurve;
				Curve curve = locationCurve.Curve;
				XYZ xyzpoint = curve.Project(ptIn).XYZPoint;
				XYZ endPoint = curve.GetEndPoint(0);
				XYZ endPoint2 = curve.GetEndPoint(1);
				XYZ xyz = Utils.SetPtZ(ptIn, endPoint.Z);
				Line line = Line.CreateUnbound(endPoint, endPoint2 - endPoint);
				XYZ xyzpoint2 = line.Project(xyz).XYZPoint;
				XYZ xyz2 = (xyz - xyzpoint2).Normalize();
				XYZ xyz3 = (endPoint - endPoint2).Normalize();
				double num2 = xyz3.AngleOnPlaneTo(xyz2, XYZ.BasisZ);
				bool flag3 = Math.Abs(num2 - Math.PI*.5) >= 0.001;
				num = 0.0;
				double num3 = 0.0;
				double num4 = 0.0;
				IList<CompoundStructureLayer> layers = compoundStructure.GetLayers();
				foreach (CompoundStructureLayer compoundStructureLayer in layers)
				{
                    bool flag4 = (int)compoundStructureLayer.Function == 1;
					if (flag4)
					{
						num += compoundStructureLayer.Width;
					}
					else
					{
						bool flag5 = num > 0.0;
						if (flag5)
						{
							num4 += compoundStructureLayer.Width;
						}
						else
						{
							num3 += compoundStructureLayer.Width;
						}
					}
				}
				double num5 = num + num3 + num4;
				bool flag6 = flag3;
				double num6;
				if (flag6)
				{
					num = num5 / 2.0 - num3;
					num6 = num5 / 2.0 - num4;
				}
				else
				{
					num = num5 / 2.0 - num4;
					num6 = num5 / 2.0 - num3;
				}
				if (bOtherSide)
				{
					num = num6;
				}
				num = HSFamily.feetToMM(num);
			}
			return num;
		}

		public static double GetBoardStructureThick(Element board, ref double dUpDianCengThick, ref double dDownDianCengThick)
		{
			double num = 0.0;
			dUpDianCengThick = 0.0;
			Floor floor = board as Floor;
			FloorType floorType = floor.FloorType;
			bool flag = floorType != null;
			if (flag)
			{
				Parameter parameter = floorType.get_Parameter(Autodesk.Revit.DB.BuiltInParameter.FLOOR_ATTR_THICKNESS_PARAM);
				bool flag2 = parameter != null;
				if (flag2)
				{
					num = parameter.AsDouble();
				}
				num = HSFamily.feetToMM(num);
				double num2 = num;
				CompoundStructure compoundStructure = floorType.GetCompoundStructure();
				bool flag3 = compoundStructure == null;
				if (flag3)
				{
					return num;
				}
				num = 0.0;
				num2 = 0.0;
				IList<CompoundStructureLayer> layers = compoundStructure.GetLayers();
				foreach (CompoundStructureLayer compoundStructureLayer in layers)
				{
                    bool flag4 = (int)compoundStructureLayer.Function == 1;
					if (flag4)
					{
						num += compoundStructureLayer.Width;
					}
					else
					{
						bool flag5 = num <= 0.0;
						if (flag5)
						{
							dUpDianCengThick += compoundStructureLayer.Width;
						}
					}
					num2 += compoundStructureLayer.Width;
				}
				num = HSFamily.feetToMM(num);
				dUpDianCengThick = HSFamily.feetToMM(dUpDianCengThick);
				num2 = HSFamily.feetToMM(num2);
				dDownDianCengThick = num2 - num - dUpDianCengThick;
			}
			return num;
		}

		public static double GetBeamHigh(Element beam)
		{
			double num = 0.0;
			FamilyInstance familyInstance = beam as FamilyInstance;
			bool flag = familyInstance == null;
			double result;
			if (flag)
			{
				result = 0.0;
			}
			else
			{
				FamilySymbol symbol = familyInstance.Symbol;
				bool flag2 = symbol == null;
				if (flag2)
				{
					result = 0.0;
				}
				else
				{
					ParameterSet parameters = symbol.Parameters;
					foreach (object obj in parameters)
					{
						Parameter parameter = (Parameter)obj;
						string name = parameter.Definition.Name;
						bool flag3 = name == "h";
						if (flag3)
						{
							num = HSFamily.feetToMM(parameter.AsDouble());
							break;
						}
					}
					result = num;
				}
			}
			return result;
		}

		public static double GetBeamWide(Element beam)
		{
			double num = 0.0;
			FamilyInstance familyInstance = beam as FamilyInstance;
			bool flag = familyInstance == null;
			double result;
			if (flag)
			{
				result = 0.0;
			}
			else
			{
				FamilySymbol symbol = familyInstance.Symbol;
				bool flag2 = symbol == null;
				if (flag2)
				{
					result = 0.0;
				}
				else
				{
					ParameterSet parameters = symbol.Parameters;
					foreach (object obj in parameters)
					{
						Parameter parameter = (Parameter)obj;
						string name = parameter.Definition.Name;
						bool flag3 = name == "b";
						if (flag3)
						{
							num = HSFamily.feetToMM(parameter.AsDouble());
							break;
						}
					}
					result = num;
				}
			}
			return result;
		}

		public static bool Is2PipeParallel(Element pipe1, Element pipe2)
		{
			MEPCurve mepcurve = pipe1 as MEPCurve;
			MEPCurve mepcurve2 = pipe2 as MEPCurve;
			bool flag = mepcurve == null || mepcurve2 == null;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				LocationCurve locationCurve = mepcurve.Location as LocationCurve;
				LocationCurve locationCurve2 = mepcurve2.Location as LocationCurve;
				XYZ xyz = locationCurve.Curve.GetEndPoint(0) - locationCurve.Curve.GetEndPoint(1);
				XYZ xyz2 = locationCurve2.Curve.GetEndPoint(0) - locationCurve2.Curve.GetEndPoint(1);
				xyz = xyz.Normalize();
				xyz2 = xyz2.Normalize();
				double num = 0.001;
				bool flag2 = !xyz.IsAlmostEqualTo(xyz2, num) && !xyz.IsAlmostEqualTo(-xyz2, num);
				result = !flag2;
			}
			return result;
		}

		public static bool Is2PipeCodirectional(Element pipe1, Element pipe2)
		{
			MEPCurve mepcurve = pipe1 as MEPCurve;
			MEPCurve mepcurve2 = pipe2 as MEPCurve;
			bool flag = mepcurve == null || mepcurve2 == null;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				LocationCurve locationCurve = mepcurve.Location as LocationCurve;
				LocationCurve locationCurve2 = mepcurve2.Location as LocationCurve;
				XYZ xyz = locationCurve.Curve.GetEndPoint(0) - locationCurve.Curve.GetEndPoint(1);
				XYZ xyz2 = locationCurve2.Curve.GetEndPoint(0) - locationCurve2.Curve.GetEndPoint(1);
				xyz = xyz.Normalize();
				xyz2 = xyz2.Normalize();
				double num = 0.001;
				result = xyz.IsAlmostEqualTo(xyz2, num);
			}
			return result;
		}

		public static string GetInstallAppRootPath()
		{
			string text = Assembly.GetExecutingAssembly().Location;
			int length = text.LastIndexOf("\\");
			text = text.Substring(0, length);
			length = text.LastIndexOf("\\");
			return text.Substring(0, length);
		}

		public static string GetTemplateDir(UIApplication uiApp)
		{
			string str = Utils.GetInstallAppRootPath();
			string versionNumber = uiApp.Application.VersionNumber;
			str += "\\FamilyLib\\Templates\\";
			str += versionNumber;
			return str + "\\";
		}

		public static bool IsStringNumber(string strVal)
		{
			long num = 0L;
			return long.TryParse(strVal, out num);
		}

		public static bool IsStringDouble(string strVal)
		{
			double num = 0.0;
			return Utils.IsStringDouble(strVal, ref num);
		}

		public static bool IsStringDouble(string strVal, ref double dVal)
		{
			return double.TryParse(strVal, out dVal);
		}

		public static Level GetLevel(string strLevelName, Autodesk.Revit.DB.Document doc)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeof(Level));
			FilteredElementIterator elementIterator = filteredElementCollector.GetElementIterator();
			elementIterator.Reset();
			while (elementIterator.MoveNext())
			{
				Element element = elementIterator.Current;
				Level level = element as Level;
				bool flag = level == null;
				if (!flag)
				{
					bool flag2 = level.Name == strLevelName;
					if (flag2)
					{
						return level;
					}
				}
			}
			return null;
		}

		public static double mmToFeet(double mmVal)
		{
			return mmVal / 304.8;
		}

		public static double feetToMM(double feetVal)
		{
			return feetVal * 304.8;
		}

		public static bool getLineCrossPoint(ref XYZ ptCross, Line ln1, Line ln2)
		{
			IntersectionResultArray intersectionResultArray;
			SetComparisonResult setComparisonResult = ln1.Intersect(ln2, out intersectionResultArray);
			bool flag = setComparisonResult != SetComparisonResult.Overlap;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				bool flag2 = intersectionResultArray.Size != 1;
				if (flag2)
				{
					result = false;
				}
				else
				{
					ptCross = intersectionResultArray.get_Item(0).XYZPoint;
					result = true;
				}
			}
			return result;
		}

		public static bool createModelLine(XYZ ptS, XYZ ptE, Autodesk.Revit.DB.Document doc, UIApplication uiApp, bool bCreateTrans = true)
		{
			Transaction transaction = new Transaction(doc, "CreateLine");
			if (bCreateTrans)
			{
				transaction.Start();
			}
			XYZ xyz = (ptE - ptS).Normalize();
			xyz = xyz.CrossProduct(XYZ.BasisZ);
			Plane plane = RevitVersionFuncs.CreatePlanByOriginAndBasis(ptS, ptS - ptE, xyz);
			SketchPlane sketchPlane = SketchPlane.Create(doc, plane);
			doc.Create.NewModelCurve(Line.CreateBound(ptS, ptE), sketchPlane);
			if (bCreateTrans)
			{
				transaction.Commit();
			}
			return true;
		}

		public static XYZ getCloestPointOnCurve(XYZ ptIn, Curve curveIn, bool bExtend = true)
		{
			XYZ result = null;
			bool flag = !bExtend;
			if (flag)
			{
				IntersectionResult intersectionResult = curveIn.Project(ptIn);
				bool flag2 = intersectionResult != null;
				if (flag2)
				{
					result = new XYZ(intersectionResult.XYZPoint.X, intersectionResult.XYZPoint.Y, intersectionResult.XYZPoint.Z);
				}
			}
			else
			{
				Line line = curveIn as Line;
				bool flag3 = line != null;
				if (flag3)
				{
					Line line2 = Line.CreateUnbound(line.GetEndPoint(0), line.GetEndPoint(1) - line.GetEndPoint(0));
					IntersectionResult intersectionResult2 = line2.Project(ptIn);
					bool flag4 = intersectionResult2 != null;
					if (flag4)
					{
						result = new XYZ(intersectionResult2.XYZPoint.X, intersectionResult2.XYZPoint.Y, intersectionResult2.XYZPoint.Z);
					}
				}
				else
				{
					Arc arc = curveIn as Arc;
					bool flag5 = arc != null;
					if (flag5)
					{
						Plane plane = RevitVersionFuncs.CreatePlanByNormalAndOrigin(arc.Normal, arc.Center);
						Arc arc2 = Arc.Create(plane, arc.Radius, 0.0, Math.PI*2);
						IntersectionResult intersectionResult3 = arc2.Project(ptIn);
						bool flag6 = intersectionResult3 != null;
						if (flag6)
						{
							result = new XYZ(intersectionResult3.XYZPoint.X, intersectionResult3.XYZPoint.Y, intersectionResult3.XYZPoint.Z);
						}
					}
				}
			}
			return result;
		}

		public static bool isPointNearCurveStart(XYZ ptIn, Curve curveIn)
		{
			XYZ endPoint = curveIn.GetEndPoint(0);
			XYZ endPoint2 = curveIn.GetEndPoint(1);
			return endPoint.DistanceTo(ptIn) < endPoint2.DistanceTo(ptIn);
		}
	}
}
